home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / abuse / src / net / unix / engine.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-15  |  32.8 KB  |  1,242 lines

  1. #include "indian.hpp"
  2. #include "../inc/netface.hpp"      // net interface structures to the engine will use
  3. #include "netfile.hpp"
  4. #include "engine.hpp"
  5.  
  6. // these are the names of the fifos to create in tmp
  7. // that communitcate with the engine
  8.  
  9. #define DIN_NAME "/tmp/.abuse_ndrv_in"
  10. #define DOUT_NAME "/tmp/.abuse_ndrv_out"
  11.  
  12. // the lock files is used in case a previous net driver is already running
  13.  
  14. #define DLOCK_NAME "/tmp/.abuse_ndrv_lock"
  15.  
  16. #ifdef __sgi
  17. #define next_process() sginap(0)
  18. #else
  19. #define next_process() usleep(10)
  20. #endif
  21.  
  22.  
  23. void net_watch();
  24. void setup_ports(int comm_port, int game_port);
  25.  
  26. int no_security=0;
  27. int driver_out_fd,driver_in_fd;
  28. int shm_seg_id=-1;
  29. void *shm_addr=(void *)-1;  // shmat returns -1 on failure
  30. base_memory_struct *base;   // points to shm_addr
  31. int comm_fd=-1,             // listening socket for commincation port
  32.     game_fd=-1;
  33. char net_server[256];   // if -net option, fetch all files from "active server"
  34. int stand_alone=0;          // if we are running this stand-alone (not interfacing with the engine)
  35.  
  36. fd_set master_set;
  37. fd_set master_write_set;    // set a socket here if you detect a write_full
  38.  
  39. join_struct *join_array;      // points to an array of possible joining clients in shared memory
  40. int game_server_fd=-1,        // connection to server created by join_game()
  41.     game_server_data_fd=-1;
  42.  
  43. int packet_port;              // port used to send 'lossy' game data
  44.  
  45. void clean_up()      // on exit unattach all shared memory links
  46. {  
  47.   base->input_state=INPUT_NET_DEAD;
  48.   fprintf(stderr,"net driver : cleaning up\n");
  49.   if (shm_seg_id!=-1)
  50.     shmctl(shm_seg_id,IPC_RMID,NULL);
  51.  
  52.   if (shm_addr!=(void *)-1) 
  53.   {
  54.     shmdt((char *)shm_addr);
  55.     shm_addr=(void *)-1;
  56.   }
  57.  
  58.   if (game_fd>0) close(game_fd);
  59.   if (comm_fd>0) close(comm_fd);
  60.  
  61.   unlink(DIN_NAME);
  62.   unlink(DOUT_NAME);
  63.   unlink(DLOCK_NAME);
  64. }
  65.  
  66. #ifdef __sgi
  67. void die(...)
  68. #else
  69. void die(int why)
  70. #endif
  71.   fprintf(stderr,"dieing\n");
  72.   clean_up();
  73.   exit(0);
  74. }
  75.  
  76.  
  77. void mdie(char *reason)
  78. {
  79.   fprintf(stderr,"net driver : %s\n",reason);
  80.   die(0);
  81. }
  82.  
  83. void comm_failed()  // general communication failure with engine
  84. {
  85.   fprintf(stderr,"net driver : Error occured while trying to communicate with the engine\n");
  86.   clean_up();
  87.   exit(0);
  88. }
  89.  
  90.  
  91. main(int argc, char **argv)
  92. {
  93.   int i;
  94.   strcpy(default_fs_name,"");          // initially no default file server
  95.   strcpy(net_server,"");
  96.  
  97.   for (i=1;i<argc;i++)
  98.     if (!strcmp(argv[i],"-bastard"))   // this bypasses filename security features
  99.     {
  100.       fprintf(stderr,"Warning : Security measures bypassed (-bastard)\n");
  101.       no_security=1;
  102.     }
  103.  
  104.  
  105.   // make sure this program was run by the abuse engine
  106.   if (argc<2 || strcmp(argv[1],"runme"))   
  107.   { 
  108.     stand_alone=1;
  109.     fprintf(stderr,"%s is normally run by abuse, running stand-alone file server\n"
  110.                "Server will be killed by running abuse\n",argv[0]);
  111.   }
  112.  
  113.  
  114.   // see if we are already running, if so kill old driver
  115.   FILE *fp=fopen(DLOCK_NAME,"rb");
  116.   if (fp)
  117.   {
  118.     int pid;
  119.     if (fscanf(fp,"%d",&pid)==1)
  120.     {
  121.       struct stat st;
  122.       char proc_path[50];
  123.       sprintf(proc_path,"/proc/%d",pid);
  124.       if (!stat(proc_path,&st))
  125.       {
  126.     fprintf(stderr,"net driver : warning, %s already running, attempting to kill...\n",argv[0]);
  127.     if (kill(pid,SIGKILL))
  128.     {
  129.       fprintf(stderr,"net driver : unable to kill process %d, cannot run net-abuse\n",pid);
  130.       fclose(fp);
  131.       return 0;
  132.     }
  133.     fprintf(stderr,"killed process %d\n",pid);
  134.       }
  135.     }
  136.     fclose(fp);
  137.     unlink(DLOCK_NAME);    
  138.   }
  139.  
  140.  
  141.   unlink(DIN_NAME);    // remove any previous files if they exsists
  142.   unlink(DOUT_NAME);
  143.  
  144.  
  145.   if (!stand_alone)
  146.   {
  147.     if (mkfifo(DIN_NAME,S_IRWXU | S_IRWXG | S_IRWXO))
  148.     { perror("Net driver : unable to make fifo in /tmp");
  149.       return 0;
  150.     }
  151.     chmod(DIN_NAME,S_IRWXU | S_IRWXG | S_IRWXO);   // just to be sure umask doesn't screw us
  152.  
  153.     if (mkfifo(DOUT_NAME,S_IRWXU | S_IRWXG | S_IRWXO))
  154.     { perror("Net driver : unable to make fifo in /tmp");
  155.       return 0;
  156.     }
  157.     chmod(DOUT_NAME,S_IRWXU | S_IRWXG | S_IRWXO);
  158.  
  159.     int i,no_fork=0;
  160.     for (i=1;i<argc;i++)
  161.     if (!strcmp(argv[i],"-no_fork"))    // use this to debug easier
  162.       no_fork=1;
  163.     
  164.     if (!no_fork)      // use this for debugging
  165.     {
  166.       int child_pid=fork();
  167.       if (child_pid)
  168.       {
  169.     FILE *fp=fopen(DLOCK_NAME,"wb");
  170.     if (!fp)
  171.     { 
  172.       fprintf(stderr,"Unable to open %s for writing, killing child\n",DLOCK_NAME);
  173.       kill(child_pid,SIGKILL);
  174.       return 0;
  175.     }
  176.     fprintf(fp,"%d\n",child_pid);
  177.     fclose(fp);
  178.     printf("%d\n",child_pid);         // tell parent the sound driver's process number
  179.     return 0;                         // exit, child will continue
  180.       }
  181.     }  
  182.  
  183.     driver_out_fd=open(DOUT_NAME,O_RDWR);  // open the pipe
  184.     if (driver_out_fd<0)
  185.     { perror(DOUT_NAME); 
  186.       exit(1);
  187.     }
  188.  
  189.     driver_in_fd=open(DIN_NAME,O_RDWR);
  190.     if (driver_in_fd<0)
  191.     { perror(DIN_NAME); 
  192.       exit(1);
  193.     }
  194.   } else driver_in_fd=driver_out_fd=-1;
  195.  
  196.  
  197.  
  198.   int catch_sigs[]={SIGHUP,SIGINT,SIGQUIT,SIGILL,SIGABRT,
  199.             SIGIOT,SIGFPE,SIGKILL,SIGUSR1,SIGSEGV,
  200.             SIGUSR2,SIGPIPE,SIGTERM,SIGCHLD,
  201.             SIGCONT,SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU,-1};
  202.  
  203.   for (i=0;catch_sigs[i]!=-1;i++)     // catch all signals in case we get
  204.     signal(catch_sigs[i],die);            // interrupted before we remove shmid
  205.  
  206.  
  207. /*  struct sigaction sa;
  208.   memset(&sa,0,sizeof(sa));
  209.   sa.sa_flags=SA_RESTART|SA_RESETHAND;
  210.   sa.sa_handler=send_sig;
  211.   sigaction(SIGUSR2,&sa,NULL); */
  212.  
  213.  
  214.   int alloc_size=sizeof(join_struct)*MAX_JOINERS+
  215.                  sizeof(base_memory_struct);
  216.  
  217.   shm_seg_id=shmget(IPC_PRIVATE,alloc_size,IPC_CREAT | 0777);
  218.   if (shm_seg_id==-1)
  219.     mdie("Unable to allocate shared memory");
  220.  
  221.  
  222.   shm_addr=shmat(shm_seg_id,NULL,0);  // attach as read/write
  223.   if (shm_addr==(void *)-1) 
  224.     mdie("could not attach shm seg");
  225.  
  226.   base=(base_memory_struct *)shm_addr;
  227.  
  228.   base->join_list=real2shm(join_struct,NULL);
  229.   base->mem_lock=0;
  230.   base->calc_crcs=0;
  231.   base->get_lsf=0;
  232.   base->wait_reload=0;
  233.   base->need_reload=0;
  234.   base->input_state=INPUT_COLLECTING;
  235.   base->current_tick=0;
  236.   base->packet.packet_reset();
  237.  
  238.  
  239.  
  240.   if (!stand_alone)
  241.   {
  242.     // see if we can attach this memory with the abuse engine
  243.     if (write(driver_out_fd,&shm_seg_id,sizeof(shm_seg_id))!=sizeof(shm_seg_id))
  244.       comm_failed();
  245.  
  246.     // wait for engine to ack it has attached
  247.     uchar ack=0;
  248.     if (read(driver_in_fd,&ack,1)!=1 || ack!=1)
  249.       comm_failed();
  250.   }
  251.  
  252.   
  253.   if (shmctl(shm_seg_id,IPC_RMID,NULL))  // remove the shm id
  254.     mdie("could not remove shm id");
  255.  
  256.   shm_seg_id=-1;                      // mark as not allocated
  257.  
  258.  
  259.   int comm_port=DEFAULT_COMM_PORT;
  260.   int game_port=-1;
  261.   for (i=1;i<argc-1;i++)
  262.     if (!strcmp(argv[i],"-port"))
  263.     {
  264.       comm_port=atoi(argv[i+1]);
  265.       if (game_port==-1)
  266.         game_port=comm_port+1;
  267.     }
  268.     else if (!strcmp(argv[i],"-game_port"))
  269.       game_port=atoi(argv[i+1]);
  270.     else if (!strcmp(argv[i],"-net"))
  271.     { strcpy(net_server,argv[i+1]); }
  272.  
  273.   if (game_port==-1) game_port=DEFAULT_GAME_PORT+1;
  274.  
  275.   setup_ports(comm_port,game_port);
  276.  
  277.  
  278.   net_watch();                        // now go into infinite block/read/process cycle
  279.  
  280.   return 0;
  281. }
  282.  
  283. client *first_client=NULL;
  284.  
  285.  
  286. void setup_ports(int comm_port, int game_port)
  287. {
  288.   sockaddr_in host;
  289.  
  290.  
  291.   game_fd=socket(AF_INET,SOCK_DGRAM,0);
  292.   if (game_fd==-1)
  293.     mdie("net driver : could not create a socket.  (too many open files?)");
  294.  
  295.   int zz;
  296.   if (setsockopt(game_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&zz,sizeof(zz))<0)
  297.     mdie("could not set socket option reuseaddr");
  298.  
  299. //  if (fcntl(game_fd,F_SETFL,FNDELAY)==-1)
  300. //    mdie("cound not set udp socket to non-blocking");
  301.  
  302.   
  303.   packet_port=game_port;   // save this port, so we can send it on joining a game
  304.   memset( (char*) &host,0, sizeof(host));
  305.   host.sin_family = AF_INET;
  306.   host.sin_port = lstl(game_port);
  307.   host.sin_addr.s_addr = lltl (INADDR_ANY);
  308.   if (bind(game_fd, (struct sockaddr *) &host, sizeof(sockaddr_in))==-1)
  309.   {
  310.     fprintf(stderr,"net driver : could not bind socket to port %d\n",game_port);
  311.     die(0);
  312.   }
  313.  
  314.  
  315.   // the comminication socket is a STREAM
  316.   comm_fd=socket(AF_INET,SOCK_STREAM,0);
  317.   if (comm_fd==-1)
  318.     mdie("net driver : could not create a socket.  (too many open files?)");
  319.  
  320.  
  321.   memset( (char*) &host,0, sizeof(host));
  322.   host.sin_family = AF_INET;
  323.   host.sin_port = lstl(comm_port);
  324.   host.sin_addr.s_addr = lltl (INADDR_ANY);
  325.   if (bind(comm_fd, (struct sockaddr *) &host, sizeof(sockaddr_in))==-1)
  326.   {
  327.     fprintf(stderr,"net driver : could not bind socket to port %d",comm_port);
  328.     die(0);
  329.   }
  330.  
  331.   if (listen(comm_fd,5)==-1)
  332.   {
  333.     fprintf(stderr,"net driver : could not listen to socket on port %d\n",comm_port);    
  334.     die(0);
  335.   }
  336.  
  337.  
  338.  
  339.  
  340. }
  341.  
  342.  
  343. void delete_client(client *c)
  344. {
  345.   FD_CLR(c->socket_fd,&master_set);   // don't listen to this client anymore
  346.  
  347. }
  348.  
  349.  
  350. inline int aquire_mem_lock()
  351. {
  352.   if (base->mem_lock==0 || base->mem_lock==1)
  353.   {
  354.     base->mem_lock=1;
  355.     if (base->mem_lock==1)
  356.       return 1;
  357.   }
  358.   return 0;
  359. }
  360.  
  361. class crc_waiter
  362. {
  363.   public :
  364.   int socket_fd;
  365.   crc_waiter *next;
  366.   crc_waiter(int fd, crc_waiter *Next)
  367.   { 
  368.     FD_SET(fd,&master_set);   // set in case socket dies
  369.     socket_fd=fd;
  370.     next=Next;
  371.   } ;
  372.   ~crc_waiter() 
  373.   { 
  374.     close(socket_fd); 
  375.     FD_CLR(socket_fd,&master_set);
  376.   }    
  377. } *crc_wait_list=NULL;
  378.  
  379. class lsf_waiter
  380. {
  381.   public :
  382.   int socket_fd;
  383.   lsf_waiter *next;
  384.   lsf_waiter(int fd, lsf_waiter *Next)
  385.   { 
  386.     FD_SET(fd,&master_set);   // set in case socket dies
  387.     socket_fd=fd;
  388.     next=Next;
  389.   } ;
  390.   ~lsf_waiter() 
  391.   { 
  392.     close(socket_fd); 
  393.     FD_CLR(socket_fd,&master_set);
  394.   }    
  395. } *lsf_wait_list=NULL;
  396.  
  397.  
  398. int connect_to_server(char *&server_name, int def_port, int stream_type, int force_port)
  399. {
  400.   char name[256],*np;
  401.   np=name;
  402.   while (*server_name && *server_name!=':' && *server_name!='/')
  403.     *(np++)=*(server_name)++;
  404.   *np=0;
  405.   if (*server_name==':')
  406.   {
  407.     server_name++;
  408.     char port[256],*p;
  409.     p=port;
  410.     while (*server_name && *server_name!='/')
  411.       *(p++)=*(server_name++);
  412.     *p=0;
  413.     int x;
  414.     if (!force_port)
  415.     {
  416.       if (sscanf(port,"%d",&x)==1) def_port=x;
  417.       else return -1;
  418.     }
  419.   }
  420.  
  421.   if (*server_name=='/') server_name++;
  422.  
  423.   if (local_address(name))    // returns 1 if server name is ourself
  424.   {
  425.     fprintf(stderr,"cannot connect to %s, is a local address\n");
  426.     return -1;
  427.   }
  428.  
  429.   int socket_fd=socket(AF_INET,stream_type,0);
  430.   if (socket_fd<0) 
  431.   {
  432.     fprintf(stderr,"unable to create socket (too many open files?)\n");
  433.     return -1;
  434.   }
  435.  
  436.  
  437.   hostent *hp=gethostbyname(name);
  438.   if (!hp)
  439.   { 
  440.     fprintf(stderr,"unable to locate server named '%s'\n",name);
  441.     close(socket_fd); 
  442.     return 0;
  443.   }
  444.   
  445.  
  446.   sockaddr_in host;
  447.   memset( (char*) &host,0, sizeof(host));
  448.   host.sin_family = AF_INET;
  449.   host.sin_port = lstl(def_port);
  450.   host.sin_addr.s_addr = lltl (INADDR_ANY);
  451.   memcpy(&host.sin_addr,hp->h_addr,hp->h_length);
  452.     
  453.   if (connect(socket_fd, (struct sockaddr *) &host, sizeof(host))==-1)
  454.   { 
  455.     fprintf(stderr,"unable to connect\n");
  456.     close(socket_fd);
  457.     return -1;
  458.   }
  459.  
  460.   return socket_fd;
  461. }
  462.  
  463. int get_lsf(char *name)  // contact remot host and ask for lisp startup file filename
  464. {
  465.   char *name_start=name;
  466.   int fd=connect_to_server(name);
  467.   if (fd<0) return 0;
  468.   uchar ctype=CLIENT_LSF_WAITER;
  469.   if (write(fd,&ctype,1)!=1) { close(fd); return 0; } 
  470.   uchar len;
  471.   if (read(fd,&len,1)!=1 || len==0) { close(fd); return 0; }
  472.   if (read(fd,name_start,len)!=len) { close(fd); return 0; }
  473.   close(fd);
  474.   return 1;  
  475. }
  476.  
  477. int join_game(char *server_name)   // ask remote server for entry into game
  478. {
  479.   char sn_start[256];
  480.   strcpy(sn_start,server_name);
  481.  
  482.   int fd=connect_to_server(server_name);
  483.   uchar ctype=CLIENT_ABUSE;
  484.   if (write(fd,&ctype,1)!=1) { close(fd); return 0; } 
  485.  
  486.   // send server out game port
  487.   ushort port=lstl(packet_port);
  488.   if (write(fd,&port,2)!=2) { close(fd); return 0; }
  489.  
  490.   // read server's game port
  491.   if (read(fd,&port,2)!=2) { close(fd); return 0; }
  492.   port=lstl(port);
  493.  
  494.   ushort cnum;
  495.   if (read(fd,&cnum,2)!=2 || cnum==0) { close(fd); return 0; }
  496.   cnum=lstl(cnum);
  497.  
  498.  
  499.   game_server_fd=fd;
  500.  
  501.   server_name=sn_start;
  502.   game_server_data_fd=connect_to_server(server_name,port,SOCK_DGRAM,1);
  503.   if (game_server_data_fd<0) mdie("could not udp-connect to server");
  504.   FD_SET(game_server_fd,&master_set);
  505.  
  506.   return cnum;
  507. }
  508.  
  509. void join_new_players()  // during this section we are giving mem_lock by engine
  510. {
  511.   client *c=first_client;
  512.  
  513.   for (;c;c=c->next)     // tell all the clients to reload
  514.   {
  515.     if (!c->has_joined)
  516.     {
  517.       ushort cnum=lstl(c->client_id);
  518.       if (write(c->socket_fd,&cnum,2)!=2) { c->delete_me=1; }
  519.       c->wait_reload=1;
  520.       c->has_joined=1;
  521.     } else if (!c->delete_me)
  522.     {
  523.       uchar reload=CLCMD_RELOAD;
  524.       if (write(c->socket_fd,&reload,1)!=1) { c->delete_me=1; }
  525.       c->wait_reload=1;
  526.     }
  527.   }
  528.  
  529.   base->join_list=NULL;  // all joiners have been added
  530.  
  531. }
  532.  
  533. int waiting_server_input=1;
  534.  
  535. void add_client_input(char *buf, int size, client *c)
  536. {
  537.   base->packet.add_to_packet(buf,size);
  538.  
  539.   if (c)
  540.   {
  541.     c->wait_input=0;
  542.   }
  543.   else 
  544.   {
  545.     FD_SET(game_fd,&master_set);   // we are ready to accept other client's game data, so add the udp socket to the select list
  546.     waiting_server_input=0;
  547.   }
  548.  
  549.   int got_all=1;  
  550.   for (c=first_client;c;c=c->next)
  551.     if (c->wait_input)
  552.       got_all=0;
  553.  
  554.   if (got_all && !waiting_server_input)
  555.   {   
  556.     base->packet.calc_checksum();
  557.  
  558.     for (c=first_client;c;c=c->next)      // setup for next time, wait for all the input
  559.     {
  560.       c->wait_input=1;      
  561.       send(c->data_fd,base->packet.data,base->packet.packet_size()+base->packet.packet_prefix_size(),0);
  562.     }
  563.  
  564.     base->input_state=INPUT_PROCESSING; // tell engine to start processing
  565.     FD_CLR(game_fd,&master_set);        // don't listen to this socket until we are prepared to read next tick's game data
  566.  
  567.     waiting_server_input=1;
  568.   }
  569. }
  570.  
  571. void get_input_from_server()
  572. {
  573.   int size=read(game_fd,base->packet.data,1024);
  574.   if (size<=0)
  575.   { mdie("read <= 0 bytes from server"); }
  576.   if (base->packet.packet_size()+base->packet.packet_prefix_size()==size &&     // did we read the whole packet?
  577.       base->packet.tick_received()==base->current_tick)    // if this was the correct tick packet, then tell server to go on
  578.     base->input_state=INPUT_PROCESSING;    
  579. }
  580.  
  581. void process_engine_command()
  582. {
  583.   uchar cmd;
  584.   if (read(driver_in_fd,&cmd,1)!=1) { mdie("could not read command from engine"); }
  585.   switch (cmd)
  586.   {
  587.     case EGCMD_DIE :
  588.     {
  589.       if (!write(driver_out_fd,&cmd,1)) { mdie("could not write block ack1"); }  // send something to unblock engine
  590.       mdie("received die command");
  591.     } break;
  592.  
  593.     case NFCMD_BLOCK :
  594.     {      
  595.       if (!write(driver_out_fd,&cmd,1)) { mdie("could not write block ack1"); }  // send something to unblock engine
  596.       if (!read(driver_in_fd,&cmd,1)) { mdie("could not read block ack1"); }  // send something to block ourself
  597.     } break;
  598.  
  599.     case NFCMD_INPUT_MISSING :    // try to fetch the input via a loss-less net protocol
  600.     {
  601.       unsigned char pk[2]={CLCMD_REQUEST_RESEND,base->packet.tick_received()};
  602.  
  603.       if (net_server[0])   // if we are connected to a server ask sever to resend
  604.       {
  605.         if (write(game_server_fd,pk,2)!=2) { mdie("attept to re-fetch input failed"); }
  606.     fprintf(stderr,"sending retry request to server (%d)\n",pk[1]);
  607.       } else
  608.       {
  609.     client *c=first_client;
  610.     for (;c;c=c->next)
  611.     {
  612.       if (!c->delete_me && c->wait_input)
  613.       {
  614.         fprintf(stderr,"sending retry request to client (%d)\n",pk[1]);
  615.         if (write(c->socket_fd,pk,2)!=2) 
  616.           c->delete_me=1;
  617.       }
  618.       if (c->delete_me) fprintf(stderr,"delete this client!\n");
  619.     }
  620.       }
  621.       if (!write(driver_out_fd,&cmd,1)) { mdie("could not write block ack1"); }  // send something to unblock engine
  622.     } break;
  623.  
  624.     case NFCMD_SEND_INPUT :
  625.     {
  626.       base->packet.set_tick_received(base->current_tick);
  627.       base->input_state=INPUT_COLLECTING;  
  628.       if (!net_server[0])
  629.       {
  630.         add_client_input(NULL,0,NULL);
  631.       }
  632.       else
  633.       {
  634.     base->packet.calc_checksum();
  635.         send(game_server_data_fd,base->packet.data,base->packet.packet_size()+base->packet.packet_prefix_size(),0);
  636.       }
  637.       if (!write(driver_out_fd,&cmd,1)) { mdie("could not write send ack1"); }  // send something to unblock engine
  638.       if (!read(driver_in_fd,&cmd,1)) { mdie("could not read send ack2"); }    // read something to block ourselves for engine
  639.     } break;
  640.  
  641.     case NFCMD_RELOADED :
  642.     {
  643.       if (game_server_fd>0)
  644.       {
  645.     uchar ok=CLCMD_RELOADED;
  646.         if (!write(game_server_fd,&ok,1)) { mdie("could not send join_ok msg"); }    
  647.     next_process();
  648.       }
  649.     } break;
  650.  
  651.     case NFCMD_PROCESS_ENTRIES :  // server is telling us the player has been added into the game
  652.     {
  653.       join_new_players();
  654.     } break;
  655.  
  656.     case NFCMD_REQUEST_ENTRY :
  657.     {
  658.       uchar len;
  659.       char name[256];
  660.       if (read(driver_in_fd,&len,1)!=1) { mdie("could not read server name length"); }
  661.       if (read(driver_in_fd,name,len)!=len) { mdie("could not read server name"); }
  662.       strcpy(net_server,name);
  663.       ushort success=join_game(name);
  664.       if (write(driver_out_fd,&success,2)!=2) mdie("cound not send lsf read failure");      
  665.       next_process();
  666.     } break;
  667.  
  668.     case NFCMD_REQUEST_LSF :
  669.     {
  670.       uchar len;
  671.       char name[256];
  672.       if (read(driver_in_fd,&len,1)!=1) { mdie("could not read lsf name length"); }
  673.       if (read(driver_in_fd,name,len)!=len) { mdie("could not read lsf name"); }
  674.       if (!get_lsf(name))
  675.       {
  676.     len=0;
  677.         if (write(driver_out_fd,&len,1)!=1) mdie("cound not send lsf read failure");
  678.       } else
  679.       {
  680.     len=strlen(name)+1;
  681.     if (write(driver_out_fd,&len,1)!=1) mdie("cound not send lsf name len");
  682.     if (write(driver_out_fd,name,len)!=len) mdie("cound not send lsf name");
  683.       }     
  684.       next_process();
  685.     } break;
  686.  
  687.     case NFCMD_PROCESS_LSF :
  688.     {
  689.       uchar len,name[256];
  690.       if (read(driver_in_fd,&len,1)!=1) { mdie("could not read lsf name length"); }
  691.       if (read(driver_in_fd,name,len)!=len) { mdie("could not read lsf name"); }
  692.       while (lsf_wait_list)
  693.       {
  694.     lsf_waiter *c=lsf_wait_list;
  695.     lsf_wait_list=lsf_wait_list->next;
  696.     uchar status=1;
  697.     write(c->socket_fd,&len,1);
  698.     write(c->socket_fd,name,len);
  699.     delete c;
  700.       }
  701.       next_process();
  702.     } break;
  703.  
  704.     case NFCMD_CRCS_CALCED : 
  705.     {
  706.       while (crc_wait_list)
  707.       {
  708.     crc_waiter *c=crc_wait_list;
  709.     crc_wait_list=crc_wait_list->next;
  710.     uchar status=1;
  711.     write(c->socket_fd,&status,1);
  712.     delete c;
  713.       }
  714.       next_process();
  715.     } break;
  716.  
  717.     case NFCMD_SET_FS :
  718.     {
  719.       uchar size;
  720.       char sn[256];
  721.       if (read(driver_in_fd,&size,1)!=1) mdie("could not read filename length");
  722.       if (read(driver_in_fd,sn,size)!=size) mdie("could not read server name");
  723.       strcpy(default_fs_name,sn);
  724.       size=fetch_crcs(sn);  // return success
  725.       if (write(driver_out_fd,&size,1)!=1) mdie("could not send ok to engine");
  726.       next_process();
  727.     } break;    
  728.  
  729.     case NFCMD_OPEN :
  730.     {
  731.       uchar size[2];
  732.       char filename[300],mode[20],*fn;
  733.       fn=filename;
  734.       if (read(driver_in_fd,size,2)!=2) mdie("could not read fd on open");
  735.       if (read(driver_in_fd,filename,size[0])!=size[0]) mdie("incomplete filename");
  736.       if (read(driver_in_fd,mode,size[1])!=size[1]) mdie("incomplete mode string");
  737.       
  738.       int fd=open_file(fn,mode);
  739.       if (fd==-2)
  740.       {
  741.     uchar st[2];
  742.     st[0]=NF_OPEN_LOCAL_FILE;
  743.     st[1]=strlen(fn)+1;
  744.     if (write(driver_out_fd,st,2)!=2) comm_failed();
  745.     int size=write(driver_out_fd,fn,st[1]);
  746.     if (size!=st[1]) comm_failed();
  747.  
  748.     if (size!=st[1]) comm_failed();
  749.       } else if (fd==-1)
  750.       {
  751.     uchar st=NF_OPEN_FAILED;
  752.     if (write(driver_out_fd,&st,1)!=1) comm_failed(); 
  753.       } else
  754.       {
  755.     uchar st=NF_OPEN_REMOTE_FILE;
  756.     if (write(driver_out_fd,&st,1)!=1) comm_failed();     
  757.     if (write(driver_out_fd,&fd,sizeof(fd))!=sizeof(fd)) comm_failed();     
  758.       }
  759.       next_process();
  760.     } break;
  761.     case NFCMD_CLOSE :
  762.     case NFCMD_SIZE :
  763.     case NFCMD_TELL :
  764.     case NFCMD_SEEK :
  765.     case NFCMD_READ :
  766.     {
  767.       int fd;
  768.       if (read(driver_in_fd,&fd,sizeof(fd))!=sizeof(fd)) comm_failed();
  769.       remote_file *rf=find_rfile(fd);
  770.       if (!rf) 
  771.     mdie("bad fd for engine command");
  772.  
  773.       switch (cmd)
  774.       {
  775.     case NFCMD_CLOSE : 
  776.     { 
  777.       unlink_remote_file(rf);
  778.       delete rf; 
  779.       uchar st=1;
  780.       if (write(driver_out_fd,&st,1)!=1) comm_failed();     
  781.     } break;
  782.     case NFCMD_SIZE  :
  783.     {
  784.       if (write(driver_out_fd,&rf->size,sizeof(rf->size))!=sizeof(rf->size)) comm_failed();           
  785.     } break;
  786.     case NFCMD_TELL :
  787.     {
  788.       long offset=rf->unbuffered_tell();
  789.       if (write(driver_out_fd,&offset,sizeof(offset))!=sizeof(offset)) comm_failed();  
  790.     } break;
  791.     case NFCMD_SEEK :
  792.     {
  793.       long offset;
  794.       if (read(driver_in_fd,&offset,sizeof(offset))!=sizeof(offset)) comm_failed();
  795.       offset=rf->unbuffered_seek(offset);
  796.       if (write(driver_out_fd,&offset,sizeof(offset))!=sizeof(offset)) comm_failed();  
  797.     } break;
  798.     case NFCMD_READ :
  799.     {
  800.       long size;
  801.       if (read(driver_in_fd,&size,sizeof(size))!=sizeof(size)) comm_failed();
  802.       rf->unbuffered_read(driver_out_fd,size);
  803.     } break;
  804.       }
  805.       next_process();
  806.     } break;    
  807.     default :
  808.     { fprintf(stderr,"net driver : unknown net command %d\n",cmd); die(0); }
  809.   }   
  810. }
  811.  
  812.  
  813. int process_client_command(client *c)
  814. {
  815.   uchar cmd;
  816.   if (read(c->socket_fd,&cmd,1)!=1) return 0;
  817.   switch (cmd)
  818.   {
  819.     case CLCMD_RELOADED :
  820.     {
  821.       c->wait_reload=0;
  822.       int done=1;
  823.       for (c=first_client;c;c=c->next)
  824.         if (c->wait_reload) done=0;
  825.       if (done) base->wait_reload=0;
  826.       return 1;
  827.     } break;
  828.     case CLCMD_REQUEST_RESEND :
  829.     {
  830.       uchar tick;
  831.       if (read(c->socket_fd,&tick,1)!=1) return 0;
  832.  
  833.  
  834.       fprintf(stderr,"request for resend tick %d (game cur=%d, pack=%d, last=%d)\n",
  835.           tick,base->current_tick,base->packet.tick_received(),base->last_packet.tick_received());
  836.  
  837.       if (tick==base->last_packet.tick_received())
  838.       {
  839.     fprintf(stderr,"resending last game packet\n");
  840.     send(c->data_fd,base->last_packet.data,base->last_packet.packet_size()+base->last_packet.packet_prefix_size(),0); 
  841.       }
  842.       else if (tick==base->packet.tick_received()) // asking for current tick, make sure it's collected
  843.       {
  844.     int got_all=!waiting_server_input;
  845.     client *cc=first_client;
  846.     for (;cc;cc=cc->next)
  847.       if (cc->wait_input) got_all=0;
  848.       
  849.     if (got_all) 
  850.     {
  851.       fprintf(stderr,"resending current game packet\n");
  852.       send(c->data_fd,base->packet.data,base->packet.packet_size()+base->packet.packet_prefix_size(),0); 
  853.     } else fprintf(stderr,"current game packet not complete yet\n");
  854.       }      
  855.       return 1;
  856.     } break;
  857.   }
  858.   return 0;
  859. }
  860.  
  861.  
  862.  
  863. int isa_client(int client_id)    // sreach the list of active clients for this id and return 1 if found
  864. {
  865.   int i;
  866.   if (client_id==0) return 1;   // the server is always a client
  867.   client *c=first_client;
  868.   for (;c;c=c->next)
  869.     if (c->client_id==client_id) return 1;
  870.   return 0;  
  871. }
  872.  
  873. int join_game_client(int client_id)
  874. {
  875. }
  876.  
  877. int add_game_client(int fd, sockaddr *from)     // returns false if could not join client
  878. {  
  879.   ushort port;
  880.   if (read(fd,&port,2)!=2) { close(fd);  return 0; }
  881.   port=lstl(port);
  882.  
  883.   ushort pport=lstl(packet_port);
  884.   if (write(fd,&pport,2)!=2) { close(fd);  return 0; }  
  885.  
  886.  
  887.   int f=-1,i;
  888.   for (i=0;f==-1 && i<MAX_JOINERS;i++)
  889.     if (!isa_client(i)) 
  890.       f=i;
  891.  
  892.   if (f===-1) { close(fd); return 0; }
  893.  
  894.   ushort client_id=lstl(f);
  895.   if (write(fd,&client_id,2)!=2) { close(fd);  return 0; }    
  896.  
  897.  
  898.   join_array[f].next=base->join_list;
  899.   base->join_list=real2shm(join_struct,&join_array[f]);
  900.   join_array[f].client_id=first_free_client; 
  901.   
  902.   first_client=new client(fd,f,first_client);
  903.   memcpy(&first_client->data_address,from,sizeof(first_client->data_address));
  904.  
  905.   // data port should be one above comminication port
  906.   first_client->data_address.sin_port = lstl(port);
  907.  
  908.   first_client->data_fd=socket(AF_INET,SOCK_DGRAM,0);
  909.  
  910.   if (first_client->data_fd==-1)
  911.   {
  912.     client *c=first_client;  first_client=first_client->next; delete c;
  913.     fprintf(stderr,"net driver : could not create a socket.  (too many open files?)");
  914.     return 0;
  915.   }
  916.   
  917.   if (connect(first_client->data_fd, (struct sockaddr *) &first_client->data_address, 
  918.           sizeof(first_client->data_address))==-1)
  919.   { 
  920.     client *c=first_client;  first_client=first_client->next; delete c;
  921.     fprintf(stderr,"unable to connect upd port\n");
  922.     return 0;
  923.   }
  924.  
  925.  
  926.   return 1;
  927. }
  928.  
  929.  
  930. void add_client()
  931. {
  932.   struct sockaddr from;
  933.   int addr_len=sizeof(from);
  934.   int new_fd=accept(comm_fd,&from,&addr_len);
  935.   if (new_fd>=0)
  936.   {
  937.     char client_type;
  938.     if (read(new_fd,&client_type,1)!=1) { close(new_fd); return ; }
  939.     switch (client_type)
  940.     {
  941.       case CLIENT_NFS : add_nfs_client(new_fd);    break;
  942.       case CLIENT_ABUSE : add_game_client(new_fd,&from); break;
  943.       case CLIENT_CRC_WAITER : 
  944.       {
  945.     if (stand_alone)    // can't ask the engine if there is no engine
  946.     {
  947.       char status=0;
  948.       write(new_fd,&status,1);
  949.       close(new_fd);
  950.     } else
  951.     {
  952.       crc_wait_list=new crc_waiter(new_fd,crc_wait_list);
  953.       base->calc_crcs=1;
  954.     }
  955.       } break;
  956.       case CLIENT_LSF_WAITER : 
  957.       {
  958.     if (stand_alone)    // can't ask the engine if there is no engine
  959.     {
  960.       char status=0;
  961.       write(new_fd,&status,1);
  962.       close(new_fd);
  963.     } else
  964.     {
  965.       lsf_wait_list=new lsf_waiter(new_fd,lsf_wait_list);
  966.       base->get_lsf=1;
  967.     }
  968.       } break;
  969.     }
  970.   }
  971. }
  972.  
  973. void net_watch()
  974. {
  975.   int i;
  976.   join_array=(join_struct *) (base+1);
  977.  
  978.   for (i=0;i<MAX_JOINERS;i++)
  979.     join_array[i].client_id=-1;
  980.  
  981.  
  982.   if (!stand_alone)
  983.   {
  984.     while (!aquire_mem_lock()) { next_process(); }
  985.     base->mem_lock=0;
  986.   }
  987.  
  988.   fd_set read_set,exception_set,write_set;
  989.   
  990.   FD_ZERO(&master_set);  
  991.   FD_ZERO(&master_write_set);  
  992.   FD_SET(comm_fd,&master_set);     // new incoming connections & nfs data
  993.   if (net_server)
  994.     FD_SET(game_fd,&master_set);     // new incoming connections & nfs data
  995.  
  996.   if (!stand_alone)
  997.   {
  998.     FD_SET(driver_in_fd,&master_set);  // request from engine
  999.     FD_SET(driver_out_fd,&master_set); // check for error on messages to engine
  1000.   }
  1001.  
  1002.   while (1)
  1003.   {
  1004.     memcpy(&read_set,&master_set,sizeof(master_set));
  1005.     memcpy(&exception_set,&master_set,sizeof(master_set));
  1006.     memcpy(&write_set,&master_write_set,sizeof(master_set));
  1007.  
  1008.  
  1009.     int tsel=select(FD_SETSIZE,&read_set,&write_set,&exception_set,NULL);
  1010.  
  1011.     int check_rest=1;
  1012.     if (!stand_alone)
  1013.     {
  1014.       if (base->input_state==INPUT_COLLECTING)
  1015.       {
  1016.     // any game related data (udp) waiting to be read?
  1017.     if (FD_ISSET(game_fd,&read_set))
  1018.     {
  1019.       tsel--;
  1020.       check_rest=0;
  1021.       net_packet scratch,*use;
  1022.       
  1023.       if (net_server[0]==0)    // if we are the server, read into scratch, then "add" into base
  1024.         use=&scratch;
  1025.       else use=&base->packet;    // otherwise read directly into base because it is a complete packet from the server
  1026.  
  1027.       sockaddr_in from_addr;
  1028.       int addr_size=sizeof(from_addr);
  1029.       int bytes_received=recvfrom(game_fd,use->data,1024,0, (sockaddr *)&from_addr,&addr_size);
  1030.  
  1031.       // make sur we got a complete packet and the packet was not a previous game tick packet
  1032.       if (bytes_received==use->packet_size()+use->packet_prefix_size())
  1033.       {
  1034.         unsigned short rec_crc=use->get_checksum();
  1035.         use->calc_checksum();
  1036.         if (rec_crc==use->get_checksum())
  1037.         {
  1038.           if (base->current_tick==use->tick_received())  
  1039.           {
  1040.         if (net_server[0])   // if we are a client, tell game to process input
  1041.         base->input_state=INPUT_PROCESSING;   // tell engine to start processing
  1042.         else
  1043.         {
  1044.  
  1045.           client *f=first_client,*found=NULL;
  1046.           for (;!found &&f;f=f->next)
  1047.           if (!memcmp(&from_addr.sin_addr,&f->data_address.sin_addr,sizeof(from_addr.sin_addr)))
  1048.           found=f;
  1049.           
  1050.           if (!found)
  1051.           fprintf(stderr,"received data from unknown client\n");
  1052.           else
  1053.           add_client_input((char *)use->packet_data(),use->packet_size(),found);
  1054.         }
  1055.           } else fprintf(stderr,"received stale packet (got %d, expected %d)\n",use->tick_received(),base->current_tick);
  1056.         } else fprintf(stderr,"received packet with bad checksum\n");
  1057.       } else fprintf(stderr,"received incomplete packet\n");
  1058.     }
  1059.     base->mem_lock=0;
  1060.       }
  1061.  
  1062.       // see if we had any errors talking to the engine
  1063.       if (FD_ISSET(driver_in_fd,&exception_set) || FD_ISSET(driver_out_fd,&exception_set))
  1064.       {
  1065.     tsel--;
  1066.     check_rest=0;
  1067.         comm_failed();
  1068.       }
  1069.       
  1070.       // see if the engine has anything to say before getting to anyone else
  1071.       if (FD_ISSET(driver_in_fd,&read_set))
  1072.       {
  1073.     tsel--;
  1074.         process_engine_command();
  1075.     check_rest=0;
  1076.       }
  1077.     }
  1078.  
  1079.  
  1080.     if (check_rest && aquire_mem_lock())  // we need to change shared memory, make sure server is not using it.
  1081.     {
  1082.       if (game_server_fd==-1)    // we are a server, check all client connections
  1083.       {
  1084.     client *c,*lastc=NULL;
  1085.  
  1086.     for (c=first_client;c;)
  1087.     {
  1088.       int del=0;
  1089.       if (FD_ISSET(c->socket_fd,&exception_set))  // error?
  1090.       {
  1091.         tsel--;
  1092.         del=1;
  1093.       }
  1094.  
  1095.       // waiting for engine to process command buffer, don't read anymore yet
  1096.       else if (FD_ISSET(c->socket_fd,&read_set))  // in comming commands data from client?
  1097.       { 
  1098.         tsel--;
  1099.         if (process_client_command(c)==0)
  1100.         del=1;
  1101.  
  1102.         if (del)
  1103.         {
  1104.           if (c->wait_reload)
  1105.           {
  1106.         int done=1;
  1107.         client *d=first_client;
  1108.         for (;d;d=d->next)                // see if this was the last client to wait on reloading
  1109.         if (d->wait_reload) done=0;
  1110.         if (done) base->wait_reload=0;
  1111.           }
  1112.  
  1113.           if (lastc) lastc->next=c->next;
  1114.           else first_client=c->next;
  1115.           client *cd=c; c=c->next; delete cd;
  1116.         } else
  1117.         {
  1118.           lastc=c;
  1119.           c=c->next;
  1120.         }     
  1121.       } else c=c->next;
  1122.     }
  1123.       } else if (FD_ISSET(game_server_fd,&read_set))
  1124.       {
  1125.     uchar cmd;
  1126.     if (read(game_server_fd,&cmd,1)!=1) { mdie("unable to read command from server"); }
  1127.     switch (cmd)
  1128.     {
  1129.       case CLCMD_RELOAD :
  1130.       {
  1131.         base->need_reload=1;
  1132.       } break;
  1133.       case CLCMD_REQUEST_RESEND :
  1134.       {
  1135.         uchar tick;
  1136.         if (read(game_server_fd,&tick,1)!=1) { mdie("unable to read resend tick from server"); }
  1137.  
  1138.         fprintf(stderr,"request for resend tick %d (game cur=%d, pack=%d, last=%d)\n",
  1139.           tick,base->current_tick,base->packet.tick_received(),base->last_packet.tick_received());
  1140.  
  1141.         if (tick==base->packet.tick_received() && !waiting_server_input)    // asking for this tick?  make sure is collected
  1142.         {
  1143.           fprintf(stderr,"resending client packet to server\n");
  1144.           send(game_server_data_fd,base->packet.data,base->packet.packet_size()+base->packet.packet_prefix_size(),0); 
  1145.         }
  1146.       } break;
  1147.     }
  1148.       }
  1149.  
  1150.  
  1151.  
  1152.       if (FD_ISSET(comm_fd,&read_set))
  1153.       {
  1154.     tsel--;
  1155.         add_client();
  1156.       }
  1157.  
  1158.       nfs_client *nc,*last=NULL;
  1159.       for (nc=first_nfs_client;nc;)      // check for nfs request
  1160.       {
  1161.  
  1162.     int ok=1;
  1163.  
  1164.     if (FD_ISSET(nc->socket_fd,&exception_set))
  1165.     {
  1166.       tsel--;
  1167.       ok=0;
  1168.       fprintf(stderr,"Killing nfs client, socket went bad\n");
  1169.     } 
  1170.     else if (nc->size_to_read)
  1171.     {
  1172.       if (FD_ISSET(nc->socket_fd,&write_set))
  1173.       {
  1174.         tsel--;
  1175.         ok=nc->send_read();
  1176.       }
  1177.     }        
  1178.     else if (FD_ISSET(nc->socket_fd,&read_set))
  1179.     {
  1180.       tsel--;
  1181.       ok=process_nfs_command(nc);    // if we couldn't process the packeted, delete the connection
  1182.     }
  1183.         
  1184.     if (ok)
  1185.     {
  1186.       last=nc;
  1187.       nc=nc->next;
  1188.     } else
  1189.     {
  1190.       if (last) last->next=nc->next;
  1191.       else first_nfs_client=nc->next;
  1192.       nfs_client *c=nc;
  1193.       nc=nc->next;
  1194.       delete c;
  1195.     }
  1196.       }
  1197.  
  1198.       // check for bad sockets for people waiting on crc's
  1199.       crc_waiter *crcw=crc_wait_list,*last_crcw=NULL;
  1200.       for (;crcw;)
  1201.       {
  1202.     if (FD_ISSET(crcw->socket_fd,&exception_set))
  1203.     {
  1204.       tsel--;
  1205.       if (last_crcw) { last_crcw->next=crcw->next; crc_waiter *cc=crcw; crcw=crcw->next; delete cc; }
  1206.       else { crc_wait_list=crcw->next; delete crcw; crcw=crc_wait_list; }
  1207.     } else crcw=crcw->next;
  1208.       }
  1209.       if (!crc_wait_list) base->calc_crcs=0;
  1210.  
  1211.       // check for bad sockets for people waiting on crc's
  1212.       lsf_waiter *lsfw=lsf_wait_list,*last_lsfw=NULL;
  1213.       for (;lsfw;)
  1214.       {
  1215.     if (FD_ISSET(lsfw->socket_fd,&exception_set))
  1216.     {
  1217.       tsel--;
  1218.       if (last_lsfw) { last_lsfw->next=lsfw->next; lsf_waiter *cc=lsfw; lsfw=lsfw->next; delete cc; }
  1219.       else { lsf_wait_list=lsfw->next; delete lsfw; lsfw=lsf_wait_list; }
  1220.     } else lsfw=lsfw->next;
  1221.       }
  1222.       if (!lsf_wait_list) base->get_lsf=0;
  1223.  
  1224.       base->mem_lock=0;
  1225.  
  1226.     }   
  1227.     if (tsel)
  1228.     {
  1229. //      fprintf(stderr,"%d",tsel);
  1230.       next_process();
  1231.     }
  1232.  
  1233.   }
  1234. }
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.